package com.digitalchina.dcn.dcss.portal.util;

import com.digitalchina.dcn.dcss.portal.client.PortalClient;
import com.digitalchina.dcn.dcss.portal.protocol.PortalMessageDecoder;
import com.digitalchina.dcn.dcss.portal.protocol.PortalMessageEncoder;
import com.digitalchina.dcn.dcss.portal.server.PortalChannelHandler;
import com.digitalchina.dcn.dcss.portal.server.PortalMessageHandler;
import com.digitalchina.dcn.dcss.portal.server.PortalServer;
import io.netty.channel.socket.DatagramChannel;
import org.apache.spark.network.util.TransportConf;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by Administrator on 2016/8/23 0023.
 */
public class PortalContext {
    private final Logger logger = LoggerFactory.getLogger(PortalContext.class);

    private final TransportConf conf;

    private final PortalMessageEncoder portalEncoder;
    private final PortalMessageDecoder portalDecoder;

    // 监听AC发送的NTF_LOGOUT消息 端口
    // 用户强制下线消息
    public static final int NTF_LOGOUT_PORT = 7749;
    /** AC接收portal消息的端口，默认为2000 */
    public static final int AC_PORT = 2000;

    public static final String AUTH_TYPE_PAP = "PAP";
    public static final String AUTH_TYPE_CHAP = "CHAP";
    /** portal 消息超时响应时间，默认500ms */
    public static final int MESSAGE_TIMEOUT = 1000;
    /** 用户认证流程 超时时间 */
    public static final int AUTH_TIMEOUT = 10000;
    /** 绑定端口最大失败次数 */
    public static final int PORT_MAX_RETRIES = 16;
    /** HTTP请求超时时间 */
    public static final int HTTP_TIMEOUT = 10000;

    public PortalContext(TransportConf conf) {
        this.conf = conf;

        this.portalEncoder = new PortalMessageEncoder();
        this.portalDecoder = new PortalMessageDecoder();
    }

    /**
     * create PortalServer on the port.
     * @param host
     * @param port
     * @return
     */
    public PortalServer createPortalServer(String host, int port) {
        return new PortalServer(this, host, port);
    }
    /**
     * Portal Server's channel handler list initialize
     * @param channel
     * @param messageHandler
     * @return
     */
    public PortalChannelHandler initializePipeline(DatagramChannel channel, PortalMessageHandler messageHandler) {
        try {
            PortalChannelHandler channelHandler = new PortalChannelHandler(messageHandler);
            channel.pipeline()
                    .addLast("encoder", portalEncoder)
                    .addLast("decoder", portalDecoder)
                    // NOTE: Chunks are currently guaranteed to be returned in the order of request, but this
                    // would require more logic to guarantee if this were not part of the same event loop.
                    .addLast("handler", channelHandler);
            return channelHandler;
        } catch (RuntimeException e) {
            logger.error("Error while initializing Netty pipeline", e);
            throw e;
        }
    }

    public TransportConf getConf() { return conf; }

    public int ntfLogoutPort() {
        return conf.getInt("portal.ntf.logout.port", NTF_LOGOUT_PORT);
    }

    public String authType() {
        String authType = conf.getString("portal.auth.type", AUTH_TYPE_CHAP);
        if (AUTH_TYPE_PAP.equalsIgnoreCase(authType) ||
                AUTH_TYPE_CHAP.equalsIgnoreCase(authType)) {
            return authType;
        } else {
            return AUTH_TYPE_PAP;
        }
    }

    /**
     * portal 消息超时响应时间，单位Mill Second
     * @return
     */
    public int msgTimeoutInMill() {
        return conf.getInt("portal.message.timeout", MESSAGE_TIMEOUT);
    }

    /**
     * 用户认证流程的超时时间
     * @return
     */
    public int authTimeoutInMill() {
        return conf.getInt("portal.auth.timeout", AUTH_TIMEOUT);
    }

    /**
     * 绑定端口的最大失败次数
     * @return
     */
    public int portMaxRetries() {
        return conf.getInt("portal.port.maxRetries", PORT_MAX_RETRIES);
    }
}
